package com.eternal.widget.guqiang;

import android.content.Context;
import android.content.res.TypedArray;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.eternal.framework.utils.ConvertUtils;
import com.eternal.widget.R;

import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

/**
 * Created by Administrator
 * On 2020/5/4
 * Description:
 *
 * @author Administrator
 */
public class SingleAddProgressBar extends ConstraintLayout implements IEffectBar {
    private Listener listener;
    private Factory factory;
    private TextView title, minTitle, maxTitle, show;
    private ImageView circle;
    private View progress, progressBack;
    private int width, cWidth;
    private boolean isMax;
    private int min, distance, interval, now;
    private float px;
    private float dWidth;
    private Disposable addSubs, minusSubs;

    public SingleAddProgressBar(Context context) {
        this(context, null);
    }

    public SingleAddProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SingleAddProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        View view = View.inflate(context, R.layout.layout_single_add_progress_bar, this);
        title = view.findViewById(R.id.txt_title);
        minTitle = view.findViewById(R.id.txt_min);
        maxTitle = view.findViewById(R.id.txt_max);
        show = view.findViewById(R.id.txt_show);
        circle = view.findViewById(R.id.img_circle);
        progress = view.findViewById(R.id.v_progress);
        progressBack = view.findViewById(R.id.v_progress_background);

        addSubs = Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(final ObservableEmitter<Object> emitter) throws Exception {
                findViewById(R.id.img_add).setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (isChecked()) {
                            float x = (now - min + 1) * dWidth + cWidth / 2f;
                            moveView(x);
                            if (listener != null) {
                                listener.onDown(false);
                                listener.onChange(now);
                            }
                            emitter.onNext(v);
                        }
                    }
                });
            }
        }).debounce(500, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) {
                if (listener != null) {
                    listener.onUp(false, now);
                }
            }
        });
        minusSubs = Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(final ObservableEmitter<Object> emitter) throws Exception {
                findViewById(R.id.img_minus).setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (isChecked()) {
                            emitter.onNext(this);
                            float x = (now - min - 1) * dWidth + cWidth / 2f;
                            moveView(x);
                            if (listener != null) {
                                listener.onDown(false);
                                listener.onChange(now);
                            }
                        }
                    }
                });
            }
        }).debounce(500, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) {
                listener.onUp(false, now);
            }
        });

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SingleAddProgressBar);
        title.setText(array.getString(R.styleable.SingleAddProgressBar_title));
        minTitle.setText(array.getString(R.styleable.SingleAddProgressBar_minTitle));
        maxTitle.setText(array.getString(R.styleable.SingleAddProgressBar_maxTitle));
        distance = array.getInt(R.styleable.SingleAddProgressBar_distance, 0);
        min = array.getInt(R.styleable.SingleAddProgressBar_minNum, 0);
        interval = array.getInt(R.styleable.SingleAddProgressBar_interval, 1);
        isMax = array.getBoolean(R.styleable.SingleAddProgressBar_isMax, false);
        if (array.getBoolean(R.styleable.SingleAddProgressBar_noAdd, false)) {
            findViewById(R.id.layout_btn).setVisibility(GONE);
//            findViewById(R.id.img_add).setVisibility(GONE);
//            findViewById(R.id.img_minus).setVisibility(GONE);
        }
        array.recycle();
    }

    public void setInterval(int value) {
        interval = value;
    }

    @Override
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    /**
     * 是否按到了view上
     *
     * @param ev
     * @return
     */
    private boolean inRangeOfView(MotionEvent ev) {
        int[] location = new int[2];
        circle.getLocationOnScreen(location);
        float ivBarX = circle.getX();
        float ivBarY = circle.getY();
        float right = ivBarX + circle.getMeasuredWidth();
        float top = 0;
        float bottom = ivBarY + circle.getMeasuredHeight();
        return ev.getY() >= top && ev.getY() <= bottom && ev.getX() >= ivBarX - ConvertUtils.dp2px(30)
                && ev.getX() <= right + ConvertUtils.dp2px(30);
    }

    public void setType(String title, String minStr, String maxStr, int min, int distance) {
        this.title.setText(title);
        setValue(minStr, maxStr, min, distance);
    }

    public void setValue(String minStr, String maxStr, int min, int distance) {
        this.minTitle.setText(minStr);
        this.maxTitle.setText(maxStr);
        this.min = min;
        this.distance = distance;
        dWidth = (width - cWidth) / ((float) distance);
    }

    @Override
    public void setFactory(Factory factory) {
        this.factory = factory;
        int max = width - cWidth;
        show.setText(factory.getText((int) (circle.getTranslationX() * distance / max + min)));
    }

    @Override
    public void setProgress(float x, boolean isMax) {
        if (x == -1) {
            px = width - cWidth;
        } else {
            px = x;
        }
        this.isMax = isMax;
        moveProgress(circle.getTranslationX());
    }

    @Override
    public float getTx() {
        return circle.getTranslationX();
    }

    public void setProgress(int value) {
        moveView((value - min) * dWidth + cWidth / 2f);
        now = value;
        if (listener != null) {
            listener.onChange(value);
        }
    }

    @Override
    public int getProgress() {
        return now;
    }

    /**
     * 移动滑块
     */
    private void moveView(float x) {
        int max = width - cWidth;
        x -= cWidth / 2f;
        x = (x < 0 ? 0 : (x > max ? max : x));
        //当前移动的长度换算成显示文字
        now = Math.round(x / dWidth + min);
        if (factory != null) {
            show.setText(factory.getText(now));
        } else {
            show.setText(String.valueOf(now));
        }
        int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        show.measure(spec, spec);
        circle.setTranslationX(x);
        int tvShowTextWidth = show.getMeasuredWidth();
        float mCurrentIvBarX = circle.getX();
        if (mCurrentIvBarX == 0) {
            show.setTranslationX(0);
        } else {
            float tvshowTextX = mCurrentIvBarX + cWidth / 2f - tvShowTextWidth / 2f;
            show.setTranslationX(tvshowTextX < 0 ? 0 : tvshowTextX + tvShowTextWidth > width ? width - tvShowTextWidth : tvshowTextX);
        }
        moveProgress(x);
    }

    private void moveProgress(float x) {
        if (Math.round(px / dWidth + min) == now) {
            progress.setTranslationX(circle.getTranslationX());
            ViewGroup.LayoutParams params = progress.getLayoutParams();
            params.width = 1;
            progress.setLayoutParams(params);
            return;
        }
        if (isMax) {
            if (x > px) {
                x = width - x;
            } else {
                x = px - x + cWidth;
            }
            x = (int) x;
            if (x == 0) {
                x = width - circle.getTranslationX();
            }
            progress.setTranslationX(circle.getTranslationX());
            ViewGroup.LayoutParams params = progress.getLayoutParams();
            params.width = (int) x;
            progress.setLayoutParams(params);
        } else {
            if (x > px) {
                x = x - px;
                progress.setTranslationX(px);
            } else {
                progress.setTranslationX(0);
            }
            x = (int) x;
            if (x == 0) {
                x = 1;
            }
            ViewGroup.LayoutParams params = progress.getLayoutParams();
            params.width = (int) x;
            progress.setLayoutParams(params);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                getParent().requestDisallowInterceptTouchEvent(true);
                if (!inRangeOfView(event)) {
                    return false;
                }
                if (null != listener) {
                    listener.onDown(true);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float x = event.getX();
                if(distance==1440){
                    now = Math.round(x / dWidth + min)/15*15;
                    x=(now-min)*dWidth+cWidth / 2f;
                }
                moveView(x);
                if (null != listener) {
                    listener.onChange(now);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (null != listener) {
                    listener.onUp(true, now);
                }
            case MotionEvent.ACTION_CANCEL:
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
            default:
        }
        return true;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = progressBack.getMeasuredWidth();
        cWidth = circle.getMeasuredWidth();
        dWidth = (width - cWidth) / ((float) distance);
        if (isMax) {
            setProgress(-1, isMax);
        } else {
            setProgress(0, isMax);
        }
        post(new Runnable() {
            @Override
            public void run() {
                moveView((now - min) * dWidth + cWidth / 2f);
                if (listener != null) {
                    listener.onChange(now);
                }
            }
        });

    }

    @Override
    public boolean isChecked() {
        return true;
    }
}
